﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace SweetSQL.Data
{
    internal static class Util
    {
        public static T FirstOrDefault<T>(IEnumerable<T> list)
        {
            foreach (T item in list)
            {
                return item;
            }
            return default(T);
        }

        public static void AppendByteArray(StringBuilder builder, object value)
        {
            byte[] bytes = value as byte[];
            if (bytes == null)
            {
                builder.Append("NULL");
                return;
            }

            int length = bytes.Length;
            builder.Append("0x");
            if (length == 0)
            {
                builder.Append('0');
            }
            else
            {
                for (int i = 0; i < length; i++)
                {
                    builder.AppendFormat("{0:x2}", bytes[i]);
                }
            }
        }

        public static string Escape(object value)
        {
            if (value.GetType().IsEnum)
            {
                return ((int)value).ToString();
            }

            return value.ToString().Replace("'", "''");
        }

        public static object DefaultConvert(Type type, object value)
        {
            if (value != DBNull.Value)
            {
                switch (Type.GetTypeCode(type))
                {
                    case TypeCode.Boolean:
                        return Convert.ToBoolean(value);
                    case TypeCode.Byte:
                        return Convert.ToByte(value);
                    case TypeCode.Char:
                        return Convert.ToChar(value);
                    case TypeCode.DateTime:
                        return Convert.ToDateTime(value);
                    case TypeCode.Decimal:
                        return Convert.ToDecimal(value);
                    case TypeCode.Double:
                        return Convert.ToDouble(value);
                    case TypeCode.Int16:
                        return Convert.ToInt16(value);
                    case TypeCode.Int32:
                        return Convert.ToInt32(value);
                    case TypeCode.Int64:
                        return Convert.ToInt64(value);
                    case TypeCode.SByte:
                        return Convert.ToSByte(value);
                    case TypeCode.Single:
                        return Convert.ToSingle(value);
                    case TypeCode.String:
                        return Convert.ToString(value);
                    case TypeCode.UInt16:
                        return Convert.ToUInt16(value);
                    case TypeCode.UInt32:
                        return Convert.ToUInt32(value);
                    case TypeCode.UInt64:
                        return Convert.ToUInt64(value);
                    case TypeCode.DBNull:
                    case TypeCode.Empty:
                        return null;
                    case TypeCode.Object:
                    default:
                        return value;
                }
            }
            else
            {
                return null;
            }
        }

        public static void AppendCustomProperties(StringBuilder builder, Dictionary<string, string> properties)
        {
            if (properties != null)
            {
                foreach (var pair in properties)
                {
                    builder.Append(';');
                    builder.Append(pair.Key);
                    builder.Append('=');
                    builder.Append(pair.Value);
                }
            }
        }

        public static void ThrowIf<T>(bool expression, string error)
        {
            if (expression)
            {
                throw new ArgumentException(string.Format(error, typeof(T)));
            }
        }

        public static void ThrowIf(bool expression, string error, string parameter)
        {
            if (expression)
            {
                throw new ArgumentException(string.Format(error, parameter));
            }
        }

        public static string GetTypeName(Type type)
        {
            //TODO: need to make this work for generice types, I suppose--I could split on ` and take the 0 index
            string[] split = type.Name.Split('.');
            return split[split.Length - 1];
        }
    }
}
